package com.wt.springsamples.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wt.springsamples.biz.mybatis.mapper.*;
import com.wt.springsamples.model.*;
import com.wt.springsamples.model.dto.UserLoginInfo;
import com.wt.springsamples.model.dto.UserRoleConfigDto;
import com.wt.springsamples.model.search.TimeSearchModel;
import com.wt.springsamples.biz.service.IOrgService;
import com.wt.springsamples.biz.service.ISysRoleService;
import com.wt.springsamples.biz.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysUserRoleRefMapper sysUserRoleRefMapper;

    @Autowired
    private SysRoleMenuRefMapper sysRoleMenuRefMapper;

    @Autowired
    private SysMenuFuncRefMapper sysMenuFuncRefMapper;

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private SysFunctionMapper sysFunctionMapper;

    @Autowired
    private IOrgService orgService;

    @Autowired
    private ISysRoleService sysRoleService;

    @Override
    public SysUser selectByLoginName(String loginName) {
        return sysUserMapper.selectByLoginName(loginName);
    }

    @Override
    public <T extends TimeSearchModel> Page<SysUser> pagination(T searchModel, int pageSize, int pageIndex) {
        Page<SysUser> page = new Page(pageIndex,pageSize);
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        String nameValue  = searchModel.getPropertyValue("name",String.class);
        Integer statusValue = searchModel.getPropertyValue("status",Integer.class);
        if(StringUtils.hasText(nameValue)){
            wrapper.like("name",nameValue);
        }
        if(statusValue!=null){
            wrapper.eq("status",statusValue);
        }
        if(searchModel.getStartTime()!=null){
            wrapper.ge("create_time",searchModel.getStartTime());
        }
        if(searchModel.getEndTime()!=null){
            wrapper.le("create_time",searchModel.getEndTime());
        }
       return super.page(page, wrapper);
    }

    @Override
    public List<SysRole> getUserRoleList(long userId) {
        List<Long> roleIds = this.getRoleIdsByUserId(userId);
        return  sysRoleService.listByIds(roleIds);
    }

    @Override
    public List<Long> getRoleIdsByUserId(long userId) {
        QueryWrapper<SysUserRoleRef> queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id",userId);
        List<SysUserRoleRef> configs = sysUserRoleRefMapper.selectList(queryWrapper);
        return configs.stream().map(config-> config.getRoleId()).collect(Collectors.toList());
    }

    @Override
    public Set<Long> getSysMenuIdListByUserId(long userId){
        List<Long> roleIdList = this.getRoleIdsByUserId(userId);
        if(CollectionUtils.isEmpty(roleIdList)){
            return new LinkedHashSet<Long>();
        }
        List<SysRoleMenuRef> roleMenuConfigs = sysRoleMenuRefMapper.selectList(new QueryWrapper<>());//可以放入缓存系统
        Set<Long> menuIdList = roleMenuConfigs.stream()
                .filter(info -> roleIdList.contains(info.getRoleId()))
                .map(info -> info.getMenuId()).collect(Collectors.toSet());
        return menuIdList;
    }

    @Override
    public List<SysMenu> getSysMenuListByUserId(long userId){

        Set<Long>  menuIds = this.getSysMenuIdListByUserId(userId);
        if(CollectionUtils.isEmpty(menuIds)){
            return  new ArrayList<SysMenu>();
        }
        return  sysMenuMapper.selectBatchIds(menuIds);
    }

    @Override
    public List<SysFunction> getSysFunctionListByUserId(long userId){
        //sys_user->sys_user_role_ref->sys_role->sys_role_menu_ref->sys_menu->sys_menu_func_ref->sys_function
        Set<Long>  menuIds = this.getSysMenuIdListByUserId(userId);
        if(CollectionUtils.isEmpty(menuIds)){
            new ArrayList<SysFunction>();
        }
        QueryWrapper<SysMenuFuncRef> queryWrapper = new QueryWrapper();
        queryWrapper.in("menu_id",menuIds);
        List<SysMenuFuncRef> sysMenuFuncRefList = sysMenuFuncRefMapper.selectList(queryWrapper);
        if(CollectionUtils.isEmpty(sysMenuFuncRefList)){
            return new ArrayList<>();
        }
        Set<Long> funcIdList = sysMenuFuncRefList.stream()
                .map(info -> info.getFuncId()).collect(Collectors.toSet());
        List<SysFunction> funcList = sysFunctionMapper.selectBatchIds(funcIdList);
        return  funcList;
    }

    @Override
    public UserLoginInfo getUserLoginInfoByLoginName(String loginName) {
        UserLoginInfo userLoginInfo = new UserLoginInfo();
        SysUser sysUser = this.selectByLoginName(loginName);
        userLoginInfo.setUserId(sysUser.getId());
        userLoginInfo.setLoginName(sysUser.getLoginName());
        userLoginInfo.setName(sysUser.getName());
        userLoginInfo.setAvatar(sysUser.getAvatar());
        userLoginInfo.setEmail(sysUser.getEmail());
//        BeanUtils.copyProperties(sysUser,userLoginInfo);
        if(sysUser.getOrgId()!=null){
            Org org = orgService.getById(sysUser.getOrgId());
            userLoginInfo.setOrg(org);
        }
        //角色
        List<Long> roleIdList = this.getRoleIdsByUserId(sysUser.getId());
        if(CollectionUtils.isEmpty(roleIdList)){
            return userLoginInfo;
        }
        List<SysRole> roleList = sysRoleService.listByIds(roleIdList);
        userLoginInfo.setRoleList(roleList);
        //权限
        List<SysRoleMenuRef> roleMenuConfigs = sysRoleMenuRefMapper.selectList(new QueryWrapper<>());//可以放入缓存系统
        Set<Long> menuIdList = roleMenuConfigs.stream()
                .filter(info -> roleIdList.contains(info.getRoleId()))
                .map(info -> info.getMenuId()).collect(Collectors.toSet());

        if(CollectionUtils.isEmpty(menuIdList)){

        }
        List<SysMenu> menuList = CollectionUtils.isEmpty(menuIdList)?new ArrayList<>():sysMenuMapper.selectBatchIds(menuIdList);
        userLoginInfo.setMenuList(menuList);
        return userLoginInfo;
    }

    @Override
    public void configRole(UserRoleConfigDto userRoleConfigDto) {
        List<Long> roleIdList = userRoleConfigDto.getRoleIdList();

        List<SysUserRoleRef> configs = roleIdList.stream().map(roleId -> {
            SysUserRoleRef config = new SysUserRoleRef();
            config.setUserId(userRoleConfigDto.getUserId());
            config.setRoleId(roleId);
            return config;
        }).collect(Collectors.toList());
        super.saveBatch(SysUserRoleRef.class,configs);
    }

}
